package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gorpc"
)

// ClientCallback 实现RPC回调接口
type ClientCallback struct{}

// OnConnect 当连接建立时回调
func (c *ClientCallback) OnConnect(session *gorpc.RPCSession) {
	fmt.Printf("Connected to server (session ID: %s)\n", session.GetID())
}

// OnClose 当连接关闭时回调
func (c *ClientCallback) OnClose(session *gorpc.RPCSession, code int, reason string) {
	fmt.Printf("Disconnected from server, code: %d, reason: %s\n", code, reason)
}

// OnRequest 当收到请求时回调
func (c *ClientCallback) OnRequest(session *gorpc.RPCSession, inMsg *gorpc.RPCMessage, outMsg *gorpc.RPCMessage, timeout time.Duration) error {
	fmt.Printf("Received request from server: %s, data: %s\n", inMsg.GetMessageID(), string(inMsg.GetMessage()))

	// 处理来自服务器的 RPC 请求
	if inMsg.GetMessageID() == "server_hello" {
		fmt.Println("Received hello from server, sending response")
		outMsg.SetMessage([]byte("Hello back from client!"))
		return nil
	}

	outMsg.SetMessage([]byte("Unknown request"))
	return nil
}

// OnNotify 当收到通知时回调
func (c *ClientCallback) OnNotify(session *gorpc.RPCSession, msg *gorpc.RPCMessage) {
	fmt.Printf("Received notification from server: %s, data: %s\n", msg.GetMessageID(), string(msg.GetMessage()))
}

func main() {
	// 创建RPC客户端
	rpcClient := gorpc.NewRPCClient(&ClientCallback{})

	// 连接到服务器
	fmt.Println("Connecting to server...")
	err := rpcClient.Connect("ws://localhost:8080")
	if err != nil {
		fmt.Printf("Failed to connect to server: %v\n", err)
		return
	}
	fmt.Println("Connected to server")

	// 定时发送请求
	go func() {
		for i := 0; i < 5; i++ {
			if !rpcClient.IsConnected() {
				fmt.Println("Client disconnected, stopping echo requests")
				break
			}

			// 创建请求消息
			inMsg := gorpc.NewMessage()
			inMsg.SetMessageID("echo")
			inMsg.SetMessage([]byte(fmt.Sprintf("Echo request %d", i+1)))
			inMsg.SetProp("timestamp", fmt.Sprintf("%d", time.Now().Unix()))

			// 创建响应消息
			outMsg := gorpc.NewMessage()

			// 发送请求
			fmt.Printf("Sending request: %s\n", string(inMsg.GetMessage()))
			err := rpcClient.CallMethod(inMsg, outMsg, 10*time.Second)
			if err != nil {
				fmt.Printf("Error calling echo method: %v\n", err)
			} else {
				fmt.Printf("Received response: %s\n", string(outMsg.GetMessage()))
			}

			// 每5秒发送一次
			time.Sleep(5 * time.Second)
		}

		// 发送ping通知
		fmt.Println("Sending ping notification")
		msg := gorpc.NewMessage()
		msg.SetMessageID("ping")
		msg.SetMessage([]byte("ping"))
		rpcClient.Notify(msg)
	}()

	// 等待中断信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	fmt.Println("Closing connection...")
	rpcClient.Close("client shutdown")
}
